#pragma once
#include "slice.h"
class Buffer {
public:
	Buffer() : buf_(NULL), b_(0), e_(0), cap_(0), exp_(512) {}
	~Buffer() { delete[] buf_; }
	void clear() { delete[] buf_; buf_ = NULL; cap_ = 0; b_ = e_ = 0; }
	size_t size() const {
		if (e_ > b_)
			return e_ - b_;
		else
			return 0;
	}
	bool empty() const;
	char* data() const;
	char* begin() const;
	char* end() const;	
	size_t space()const;
	void addSize(size_t len);

	char* makeRoom(size_t len);
	void makeRoom();
	char* allocRoom(size_t len);

	Buffer& append(const char* p, size_t len);
	Buffer& append(Slice slice);
	Buffer& append(const char* p);

	template<class T> Buffer& appendValue(const T& v) { append((const char*)&v, sizeof v); return *this; }
	Buffer& consume(size_t len);
	Buffer& absorb(Buffer& buf);
	void setSuggestSize(size_t sz);
	Buffer(const Buffer& b);
	Buffer& operator=(const Buffer& b);
	operator Slice () { return Slice(data(), size()); }
private:
	char* buf_;
	size_t b_, e_, cap_, exp_;
	void moveHead() { std::copy(begin(), end(), buf_); e_ -= b_; b_ = 0; }
	void expand(size_t len);
	void copyFrom(const Buffer& b);
};

